package com.spzx.cart.service.impl;


import com.alibaba.nacos.client.naming.utils.CollectionUtils;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.spzx.api.cart.domain.CartInfo;
import com.spzx.cart.service.CartService;
import com.spzx.common.core.constant.SecurityConstants;
import com.spzx.common.core.context.SecurityContextHolder;
import com.spzx.common.core.domain.R;
import com.spzx.common.core.exception.ServiceException;
import com.spzx.product.api.RemoteProductService;
import com.spzx.product.domain.ProductSku;
import com.spzx.product.domain.SkuPrice;
import lombok.extern.slf4j.Slf4j;
import org.apache.tomcat.util.descriptor.web.SecurityCollection;
import org.hibernate.validator.internal.constraintvalidators.bv.time.futureorpresent.FutureOrPresentValidatorForReadableInstant;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.BoundHashOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

@Service
@Slf4j
public class CartServiceImpl implements CartService {
    @Autowired
    RedisTemplate redisTemplate;

    @Autowired
    RemoteProductService remoteProductService;


    private String getCartKey(Long userId) {
        //定义key user:userId:cart
        return "user:cart:" + userId;
    }


    @Override
    public void addToCart(Long skuId, Integer skuNum) {
        // 获取当前登录用户的id
        Long userId = SecurityContextHolder.getUserId();

        //1.构建“用户”购物车hash结构key  user：用户ID：cart
        //定义key user:userId:cart
        String cartKey = "user:cart:" + userId;
        Integer threshold = 99;

        //2.创建Hash结构绑定操作对象（方便对hash进行操作）
        /*
        <String, String, CartInfo> 表示：
        外层 Key 类型（即 cartKey 的类型）为 String（如 user:cart:123）。
        内层 Hash 的 field 类型为 String（通常是商品 ID，如 10001）。
        内层 Hash 的 value 类型为 CartInfo（购物车商品信息对象）。
         */
        BoundHashOperations<String, String, CartInfo> hashOps = redisTemplate.boundHashOps(cartKey);
        //4.判断用户购物车中是否包含该商品 如果包含：数量进行累加(某件商品数量上限99) 不包含：新增购物车商品
        String hashKey = skuId.toString();
        if (hashOps.hasKey(hashKey)) {
            //4.1 说明该商品在购物车中已有，对数量进行累加 ，不能超过指定上限99
            CartInfo cartInfo = hashOps.get(hashKey);//根据key获得value
            int totalCount = cartInfo.getSkuNum() + skuNum;
            cartInfo.setSkuNum(totalCount > 99 ? 99 : totalCount);
            hashOps.put(hashKey, cartInfo);
        } else {
            //3.判断购物车商品种类（不同SKU）总数大于50件
            Long size = hashOps.size();
            if (++size >= 50) {
                throw new RuntimeException("商品种类数量超过上限！");
            }
            //4. 说明购物车没有该商品，构建购物车对象，存入Redis
            CartInfo cartInfo = new CartInfo();
            cartInfo.setUserId(userId);
            cartInfo.setSkuNum(skuNum > threshold ? threshold : skuNum);
            cartInfo.setCreateTime(new Date());
            cartInfo.setUpdateTime(new Date());


            //4.1 远程调用商品服务获取商品sku基本信息
            R<ProductSku> productSkuR = remoteProductService.getProductSku(skuId, SecurityConstants.INNER);
            if (R.FAIL == productSkuR.getCode()) {
                throw new ServiceException(productSkuR.getMsg());
            }
            ProductSku productSku = productSkuR.getData();
            Long productId = productSku.getProductId();
            cartInfo.setSkuId(skuId);
            cartInfo.setSkuName(productSku.getSkuName());
            cartInfo.setThumbImg(productSku.getThumbImg());

            //4.2 远程调用商品服务获取商品实时价格
            R<SkuPrice> skuPriceR = remoteProductService.getSkuPrice(productId, SecurityConstants.INNER);
            if (R.FAIL == skuPriceR.getCode()) {
                throw new ServiceException(skuPriceR.getMsg());
            }
            SkuPrice skuPrice = skuPriceR.getData();
            cartInfo.setCartPrice(skuPrice.getSalePrice());
            cartInfo.setSkuPrice(skuPrice.getSalePrice());


            //4.3 将购物车商品存入Redis
            hashOps.put(hashKey, cartInfo);

        }
    }

    @Override
    public List<CartInfo> getCartList() {
        // 获取当前登录用户的id
        Long userId = SecurityContextHolder.getUserId();
        String cartKey = this.getCartKey(userId);
        // 从redis获取数据,
        List<CartInfo> cartInfoList = redisTemplate.opsForHash().values(cartKey);
        if (!CollectionUtils.isEmpty(cartInfoList)) {
            //确保用户能优先看到最新添加的商品
            List<CartInfo> collect = cartInfoList.stream().sorted(Comparator.comparing(CartInfo::getCreateTime, Comparator.nullsLast(Comparator.reverseOrder()))).collect(Collectors.toList());
            //List<CartInfo> collect=cartInfoList.stream().sorted((o1, o2) -> o2.getCreateTime().compareTo(o1.getCreateTime())).collect(Collectors.toList());
            //List<CartInfo> collect = cartInfoList.stream().sorted(Comparator.comparing(CartInfo::getCreateTime).reversed()).collect(Collectors.toList());

            //获取skuId列表
            List<Long> skuIdList = collect.stream().map(CartInfo::getSkuId).collect(Collectors.toList());
            //查询商品的实时价格
            R<List<SkuPrice>> skuPriceListR = remoteProductService.getSkuPriceList(skuIdList, SecurityConstants.INNER);
            if (R.FAIL == skuPriceListR.getCode()) {
                throw new ServiceException(skuPriceListR.getMsg());
            }
            List<SkuPrice> skuPriceList = skuPriceListR.getData();
            Map<Long, BigDecimal> skuIdToPriceMap = skuPriceList.stream().collect(Collectors.toMap(SkuPrice::getSkuId, SkuPrice::getSalePrice));
            collect.forEach(item -> {
                //设置实时价格
                item.setSkuPrice(skuIdToPriceMap.get(item.getSkuId()));
            });
            return collect;
        }

        return new ArrayList<>();

    }

    @Override
    public void deleteCart(Long stuId) {
        //获取当前用户id
        Long userId = SecurityContextHolder.getUserId();
        String cartKey = getCartKey(userId);
        //获取缓存对象
        BoundHashOperations<String,String,CartInfo> boundHashOperations = redisTemplate.boundHashOps(cartKey);
        boundHashOperations.delete(stuId.toString());
    }

    @Override
    public void updateCart(Long skuId, Integer isChecked) {
        //获取当前用户对象
        Long userId = SecurityContextHolder.getUserId();
        String cartKey = getCartKey(userId);
        //获取缓存
        BoundHashOperations<String,String,CartInfo> boundHashOperations = redisTemplate.boundHashOps(cartKey);
        //获取用户选择商品
        if (boundHashOperations.hasKey(skuId.toString())){
            CartInfo cartInfo = boundHashOperations.get(skuId.toString());
            cartInfo.setIsChecked(isChecked);
            //更新缓存
            boundHashOperations.put(skuId.toString(), cartInfo);
        }
    }

    @Override
    public void allCheckCart(Integer isChecked) {
        //获取用户Id
        Long userId = SecurityContextHolder.getUserId();
        String cartKey = getCartKey(userId);
        BoundHashOperations<String,String,CartInfo> boundHashOperations = redisTemplate.boundHashOps(cartKey);
        List<CartInfo> cartInfoList = boundHashOperations.values();
        cartInfoList.forEach(cartItem->{
            CartInfo cartInfo = boundHashOperations.get(cartItem.getSkuId().toString());
            cartInfo.setIsChecked(isChecked);
            //更新缓存
            boundHashOperations.put(cartItem.getSkuId().toString(), cartItem);
        });
    }

    @Override
    public void clearCart() {

        //获取用户Id
        Long userId = SecurityContextHolder.getUserId();
        //redis中的key，user:cart:{userId}
        String cartKey = getCartKey(userId);
        //
        BoundHashOperations<String,String,CartInfo> boundHashOperations = redisTemplate.boundHashOps(cartKey);
        List<CartInfo> cartInfoList = boundHashOperations.values();
        cartInfoList.forEach(item->{
            boundHashOperations.delete(item.getSkuId().toString());
        });
    }

    @Override
    public List<CartInfo> getCartCheckedList() {
        Long userId = SecurityContextHolder.getUserId();
        String cartKey = getCartKey(userId);
        //从redis中获取cartInfo放到cartInfoList中
        List<CartInfo> cartInfoList =  new ArrayList<>();
        List<CartInfo> cartInfos = redisTemplate.opsForHash().values(cartKey);
        for (CartInfo cartInfo : cartInfos) {
            //.intValue() 表示是否显式拆箱以及空指针异常的风险
            if (cartInfo.getIsChecked().intValue()==1){
                cartInfoList.add(cartInfo);
            }
        }
        return cartInfoList;
    }

    @Override
    public Boolean updateCartPrice(Long userId) {
        String cartKey = getCartKey(userId);
        //从redis取出购物车商品
        BoundHashOperations<String,String,CartInfo> boundHashOperations = redisTemplate.boundHashOps(cartKey);
        List<CartInfo> cartInfoList = boundHashOperations.values();
        if (!CollectionUtils.isEmpty(cartInfoList)) {
            for (CartInfo cartInfo : cartInfoList) {
                Long skuId = cartInfo.getSkuId();
                //查询数据库中商品实时价格
                R<ProductSku> productSkuR = remoteProductService.getProductSku(skuId, SecurityConstants.INNER);
                ProductSku productSku = productSkuR.getData();
                BigDecimal salePrice = productSku.getSalePrice();
                BigDecimal skuPrice = cartInfo.getSkuPrice();
                //如果不一致就更新价格
                if (salePrice!=skuPrice){
                    //更新实时价格
                    cartInfo.setSkuPrice(salePrice);
                    boundHashOperations.put(skuId.toString(),cartInfo);
                }
            }
        }
        return true;
    }


//    @Override
//    public List<CartInfo> getCartList() {
//        // 获取当前登录用户的id
//        Long userId = SecurityContextHolder.getUserId();
//        String cartKey = this.getCartKey(userId);
//        // 获取数据
//        List<CartInfo> cartInfoList = redisTemplate.opsForHash().values(cartKey);
//        if (!CollectionUtils.isEmpty(cartInfoList)) {
//            List<CartInfo> infoList = cartInfoList.stream()
//                    .sorted((o1, o2) -> o2.getCreateTime().compareTo(o1.getCreateTime()))
//                    .collect(Collectors.toList());
//
//            //获取skuId列表
//            List<Long> skuIdList = infoList.stream().map(CartInfo::getSkuId).collect(Collectors.toList());
//            //查询商品的实时价格
//            R<List<SkuPrice>> SkuPriceListResult = remoteProductService.getSkuPriceList(skuIdList, SecurityConstants.INNER);
//            if (R.FAIL == SkuPriceListResult.getCode()) {
//                throw new ServiceException(SkuPriceListResult.getMsg());
//            }
//            Map<Long, BigDecimal> skuIdToPriceMap = SkuPriceListResult.getData().stream().collect(Collectors.toMap(SkuPrice::getSkuId, SkuPrice::getSalePrice));
//            infoList.forEach(item -> {
//                //设置实时价格
//                item.setSkuPrice(skuIdToPriceMap.get(item.getSkuId()));
//            });
//            return infoList ;
//        }
//        return new ArrayList<>();
//    }


}
